#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# Copyright (c) 2019, Ethan Slattery
# Copyright (c) 2021, Niklas Hauser
# Copyright (c) 2022, Andrey Kunitsyn
#
# This file is part of the modm project.
#
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
# -----------------------------------------------------------------------------

import math

def init(module):
    module.name = ":platform:core"
    module.description = FileReader("module.md")

def prepare(module, options):
    if options[":target"].identifier.platform != "rp":
        return False

    module.depends(":platform:cortex-m")
    module.add_option(
        EnumerationOption(
            name="boot2",
            description="Second-stage bootloader variant",
            enumeration=["generic_03h", "at25sf128a", "is25lp080", "w25q080", "w25x10cl"],
            default="generic_03h"))
    module.add_option(
        NumericOption(
            name="boot2_size",
            description="Specify the size of external QSPI FLASH chip",
            minimum=0,
            maximum="16Mi",
            default="2Mi"))
    return True


def build(env):
    target = env[":target"].identifier

    env.substitutions = {"with_multicore": env.has_module(":platform:multicore")}
    env.outbasepath = "modm/src/modm/platform/core"
    # startup helper code
    env.template("startup_platform.cpp.in")

    # delay code that must be tuned for each family
    # (cycles per loop, setup cost in loops, max CPU freq)
    tuning = {
        "20": (3, 4, 133000000)
    }[target.family]

    # us_shift is an optimization to limit error via fractional math
    us_shift = 32 - math.ceil(math.log2(tuning[2]))

    env.substitutions.update({
        "with_cm0": env[":target"].has_driver("core:cortex-m0*"),
        "with_cm7": env[":target"].has_driver("core:cortex-m7*"),
        "loop": tuning[0],
        "shift": int(math.log2(tuning[1])),
        "us_shift": us_shift,
        "with_assert": env.has_module(":architecture:assert")
    })
    env.template("../cortex/delay_ns.cpp.in", "delay_ns.cpp")
    env.template("../cortex/delay_ns.hpp.in", "delay_ns.hpp")
    env.template("../cortex/delay_impl.hpp.in", "delay_impl.hpp")
    env.copy("resets.hpp")

    env.copy(repopath("ext/rp/pico-sdk/src/boot2_{}.cpp".format(env["boot2"])),"boot2.cpp")


def post_build(env):
    env.substitutions = env.query("::cortex-m:linkerscript")
    env.substitutions.update(env.query("::cortex-m:vector_table"))
    env.substitutions["with_multicore"] = env.has_module(":platform:multicore")
    env.outbasepath = "modm/link"
    env.template("flash.ld.in", "linkerscript.ld")
